package com.xxx.video.main.utils;

import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.TextUtils;


import androidx.fragment.app.FragmentActivity;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;

import com.xxx.video.commen.utils.FileUtils;
import com.xxx.video.commen.utils.ListUtils;
import com.xxx.video.main.beans.AlbumCheckType;
import com.xxx.video.main.beans.LocalMediaFolderInfoBean;
import com.xxx.video.main.beans.LocalMediaInfoBean;
import com.xxx.video.main.beans.MediaType;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Locale;

/**
 *
 */
public class LocalMediaUtils {
    /**
     *
     */
    private static final Uri QUERY_URI = MediaStore.Files.getContentUri("external");
    /**
     *
     */
    private static final String ORDER_BY = MediaStore.Files.FileColumns._ID + " DESC";
    /**
     *
     */
    private static final String NOT_GIF = "!='images/gif'";
    /**
     *
     */
    private boolean isGif = true;
    /**
     *
     */
    private long videoMaxS = 0;
    /**
     *
     */
    private long videoMinS = 0;
    /**
     *
     */
    private static final String DURATION = "duration";
    /**
     *
     */
    private static final String[] PROJECTION = {
            MediaStore.Files.FileColumns._ID,
            MediaStore.MediaColumns.DATA,
            MediaStore.MediaColumns.MIME_TYPE,
            MediaStore.MediaColumns.WIDTH,
            MediaStore.MediaColumns.HEIGHT,
            DURATION,
            MediaStore.MediaColumns.SIZE
    };
    /**
     *
     */
    private static final String[] SELECTION_ALL_ARGS = {
            String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE),
            String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO),
    };
    /**
     *
     */
    private static final String SELECTION = MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
            + " AND " + MediaStore.MediaColumns.SIZE + ">0";
    /**
     *
     */
    private static final String SELECTION_NOT_GIF = MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
            + " AND " + MediaStore.MediaColumns.SIZE + ">0"
            + " AND " + MediaStore.MediaColumns.MIME_TYPE + NOT_GIF;

    private static LocalMediaUtils mLocalMediaUtils = null;

    private LocalMediaUtils() {
    }

    public static LocalMediaUtils getInstance() {
        if (mLocalMediaUtils == null) {
            synchronized (LocalMediaUtils.class) {
                if (mLocalMediaUtils == null) {
                    mLocalMediaUtils = new LocalMediaUtils();
                }
            }
        }
        return mLocalMediaUtils;
    }

    /**
     *
     */
    private String getSelectionArgsForAllMediaCondition(String time_condition, boolean isGif) {
        return "(" + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
                + (isGif ? "" : " AND " + MediaStore.MediaColumns.MIME_TYPE + NOT_GIF)
                + " OR "
                + (MediaStore.Files.FileColumns.MEDIA_TYPE + "=? AND " + time_condition) + ")"
                + " AND " + MediaStore.MediaColumns.SIZE + ">0";
    }

    /**
     *
     */
    private String getSelectionArgsForSingleMediaCondition(String time_condition) {
        return MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
                + " AND " + MediaStore.MediaColumns.SIZE + ">0"
                + " AND " + time_condition;
    }

    /**
     *
     */
    private String[] getSelectionArgsForSingleMediaType(int mediaType) {
        return new String[]{String.valueOf(mediaType)};
    }

    /**
     *
     */
    public void loadAllLocalMediaData(FragmentActivity activity, int albumCheckType, OnLoadLocalMediaListener onLoadLocalMediaListener) {
        if (activity == null) {
            return;
        }
        activity.getSupportLoaderManager().initLoader(albumCheckType, null, new LoaderManager.LoaderCallbacks<Cursor>() {
            /**
             */
            @Override
            public Loader<Cursor> onCreateLoader(int id, Bundle args) {
                CursorLoader cursorLoader = null;
                switch (id) {
                    case AlbumCheckType.ALL:
                        /*
                         * all
                         */
                        String all_condition = getSelectionArgsForAllMediaCondition(getDurationCondition(0, 0), isGif);
                        cursorLoader = new CursorLoader(
                                activity, QUERY_URI,
                                PROJECTION, all_condition,
                                SELECTION_ALL_ARGS, ORDER_BY);

                        break;
                    case AlbumCheckType.ONLY_IMAGE:
                        /*
                         * image
                         */
                        String[] MEDIA_TYPE_IMAGE = getSelectionArgsForSingleMediaType(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE);
                        cursorLoader = new CursorLoader(
                                activity, QUERY_URI,
                                PROJECTION, isGif ? SELECTION : SELECTION_NOT_GIF, MEDIA_TYPE_IMAGE
                                , ORDER_BY);
                        break;
                    case AlbumCheckType.ONLY_VIDEO:
                        /*
                         * video
                         */
                        String video_condition = getSelectionArgsForSingleMediaCondition(getDurationCondition(0, 0));
                        String[] MEDIA_TYPE_VIDEO = getSelectionArgsForSingleMediaType(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO);
                        cursorLoader = new CursorLoader(
                                activity, QUERY_URI, PROJECTION, video_condition, MEDIA_TYPE_VIDEO
                                , ORDER_BY);
                        break;
                }
                return cursorLoader;
            }

            /**
             */
            @Override
            public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
                try {
                    /*
                     */
                    ArrayList<LocalMediaFolderInfoBean> localMediaFolderInfoBeanList = new ArrayList<>();
                    /*
                     */
                    LocalMediaFolderInfoBean allLocalMediaFolderInfoBean = new LocalMediaFolderInfoBean();
                    /*
                     */
                    ArrayList<LocalMediaInfoBean> allLocalMediaInfoBeanList = new ArrayList<>();
                    if (data != null && data.getCount() > 0) {
                        /*
                         */
                        data.moveToFirst();
                        do {
                            /*
                             */
                            String path = data.getString(data.getColumnIndexOrThrow(PROJECTION[1]));
                            /*
                             */
                            String pictureType = data.getString(data.getColumnIndexOrThrow(PROJECTION[2]));
                            /*
                             */
                            int width = data.getInt(data.getColumnIndexOrThrow(PROJECTION[3]));
                            /*
                             */
                            int height = data.getInt(data.getColumnIndexOrThrow(PROJECTION[4]));
                            /*
                             */
                            int duration = data.getInt(data.getColumnIndexOrThrow(PROJECTION[5]));
                            /*
                             */
                            long size = data.getLong(data.getColumnIndexOrThrow(PROJECTION[6]));
                            /*
                             */
                            String name = getFileNameByPath(path);
                            /*
                             */
                            if (FileUtils.getInstance().fileIsExist(path) && fileNameIsLegal(name)) {
                                LocalMediaInfoBean localMediaInfoBean = new LocalMediaInfoBean();
                                /*
                                 */
                                localMediaInfoBean.path = path;
                                /*
                                 */
                                localMediaInfoBean.duration = duration;
                                /*
                                 */
                                localMediaInfoBean.height = height;
                                /*
                                 */
                                localMediaInfoBean.width = width;
                                /*
                                 */
                                localMediaInfoBean.mMediaType = getMediaTypeByPictureType(pictureType);
                                /*
                                 */
                                localMediaInfoBean.pictureType = pictureType;
                                /*
                                 */
                                localMediaInfoBean.fileSize = size;
                                /*
                                 */
                                allLocalMediaInfoBeanList.add(localMediaInfoBean);
                                /*
                                 */
                                LocalMediaFolderInfoBean localMediaFolderInfoBean = getLocalMediaFolderInfoBean(path, localMediaFolderInfoBeanList);
                                /*
                                 */
                                if (ListUtils.isEmpty(localMediaFolderInfoBean.mLocalMediaInfoBeanList)) {
                                    localMediaFolderInfoBean.mLocalMediaInfoBeanList = new ArrayList<>();
                                }
                                localMediaFolderInfoBean.mLocalMediaInfoBeanList.add(localMediaInfoBean);

                            }
                        } while (data.moveToNext());

                        /*
                         */
                        if (allLocalMediaInfoBeanList.size() > 0) {
                            /*
                             */
                            sortFolder(localMediaFolderInfoBeanList);
                            /*
                             */
                            localMediaFolderInfoBeanList.add(0, allLocalMediaFolderInfoBean);
                            /*
                             */
                            allLocalMediaFolderInfoBean.fileFolderName = "";
                            /*
                             */
                            allLocalMediaFolderInfoBean.mLocalMediaInfoBeanList = allLocalMediaInfoBeanList;
                            /*
                             */
                            allLocalMediaFolderInfoBean.firstMediaPath = allLocalMediaInfoBeanList.get(0).path;
                        }
                        /*
                         */
                        if (onLoadLocalMediaListener != null) {
                            onLoadLocalMediaListener.onLoadFinish(localMediaFolderInfoBeanList);
                        }
                    } else {
                        if (onLoadLocalMediaListener != null) {
                            onLoadLocalMediaListener.onLoadError();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    if (onLoadLocalMediaListener != null) {
                        onLoadLocalMediaListener.onLoadError();
                    }
                }

            }

            @Override
            public void onLoaderReset(Loader<Cursor> loader) {

            }
        });
    }

    /**
     *
     */
    private void sortFolder(ArrayList<LocalMediaFolderInfoBean> imageFolders) {
        Collections.sort(imageFolders, (lhs, rhs) -> {
            int lsize = lhs.getMediaNum();
            int rsize = rhs.getMediaNum();
            return Integer.compare(rsize, lsize);
        });
    }

    /**
     *
     */
    private LocalMediaFolderInfoBean getLocalMediaFolderInfoBean(String path, ArrayList<LocalMediaFolderInfoBean> localMediaFolderInfoBeanList) {
        /*
         */
        File file = new File(path);
        /*
         */
        File folderFile = file.getParentFile();
        if (!ListUtils.isEmpty(localMediaFolderInfoBeanList)) {
            for (LocalMediaFolderInfoBean localMediaFolderInfoBeanTemp : localMediaFolderInfoBeanList) {
                if (localMediaFolderInfoBeanTemp.fileFolderName.equals(folderFile.getName())) {
                    /*
                     */
                    return localMediaFolderInfoBeanTemp;
                }
            }
        }
        /*
         */
        LocalMediaFolderInfoBean localMediaFolderInfoBean = new LocalMediaFolderInfoBean();
        localMediaFolderInfoBean.fileFolderName = folderFile.getName();
        localMediaFolderInfoBean.fileFolderPath = folderFile.getAbsolutePath();
        localMediaFolderInfoBean.firstMediaPath = path;
        localMediaFolderInfoBeanList.add(localMediaFolderInfoBean);
        return localMediaFolderInfoBean;
    }

    /**
     *
     */
    private String getFileNameByPath(String path) {
        if (TextUtils.isEmpty(path)) {
            return "";
        }
        int start = path.lastIndexOf("/");
        if (start != -1) {
            return path.substring(start + 1);
        } else {
            return "";
        }
    }

    /**
     *
     */
    private boolean fileNameIsLegal(String fileName) {
        if (TextUtils.isEmpty(fileName)) {
            return false;
        }
        return !fileName.contains("@") && !fileName.contains("#") && !fileName.contains("%") && !fileName.contains("{") && !fileName.contains("[") && !fileName.contains("$");
    }

    /**
     *
     */
    private MediaType getMediaTypeByPictureType(String pictureType) {
        if (TextUtils.isEmpty(pictureType)) {
            return MediaType.IMAGE;
        }
        switch (pictureType) {
            case "images/png":
            case "images/PNG":
            case "images/jpeg":
            case "images/JPEG":
            case "images/webp":
            case "images/WEBP":
            case "images/gif":
            case "images/bmp":
            case "images/GIF":
            case "imagex-ms-bmp":
                return MediaType.IMAGE;
            case "video/3gp":
            case "video/3gpp":
            case "video/3gpp2":
            case "video/avi":
            case "video/mp4":
            case "video/quicktime":
            case "video/x-msvideo":
            case "video/x-matroska":
            case "video/mpeg":
            case "video/webm":
            case "video/mp2ts":
            case "video/*":
                return MediaType.VIDEO;
            case "audio/mpeg":
            case "audio/x-ms-wma":
            case "audio/x-wav":
            case "audio/amr":
            case "audio/wav":
            case "audio/aac":
            case "audio/mp4":
            case "audio/quicktime":
            case "audio/lamr":
            case "audio/3gpp":
                return MediaType.AUDIO;
        }
        return MediaType.IMAGE;
    }


    /**
     *
     */
    private String getDurationCondition(long exMaxLimit, long exMinLimit) {
        long maxS = videoMaxS == 0 ? Long.MAX_VALUE : videoMaxS;
        if (exMaxLimit != 0) {
            maxS = Math.min(maxS, exMaxLimit);
        }

        return String.format(Locale.CHINA, "%d <%s duration and duration <= %d",
                Math.max(exMinLimit, videoMinS),
                Math.max(exMinLimit, videoMinS) == 0 ? "" : "=",
                maxS);
    }

}
